package com.hmdp.utils.listener;

import com.hmdp.entity.VoucherOrder;
import com.hmdp.service.IVoucherOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @package: com.hmdp.utils
 * @className: SpringRabbitMQ
 * @author: 云溪
 * @description:
 * @date: 2025/9/16 9:08
 * @version: 1.0
 */
@Slf4j
@Component
public class SpringRabbitMQListener {

    @Resource
    private IVoucherOrderService voucherOrderService;

    /**
     * 监听direct.queue消息队列，如果不存在
     * 就创建相关交换机，队列和绑定关系，然后进行消费
     * 配置文件里开启了prefetch = 1 线程会抢占式获取消息队列信息
     * @param voucherOrder 优惠券订单信息
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(
                    name = "direct.queue", durable = "true",
                    arguments = @Argument(name = "x-queue-mode", value = "lazy")),// 设置消息队列默认为持久化和开启lazy队列模式（消息会直接存入磁盘，避免内存爆仓。）
            exchange = @Exchange(name = "seckill.direct", type = ExchangeTypes.DIRECT),//设置交换机名称和类型，默认为DIRECT类型与自动持久化
            key = "seckill.order" //设置队列绑定的RoutingKey
    ),
            concurrency = "1-10" //启动动态线程池（最低1个，最多10个）并发消费
    )
    public void listenMassage(VoucherOrder voucherOrder, Message message){
        log.debug("接收到的消息 ID：{}", message.getMessageProperties().getMessageId());
        log.debug("线程：{} - 收到优惠券订单消息：{}", Thread.currentThread().getId(), voucherOrder);
        voucherOrderService.createVoucherOrder(voucherOrder);
    }

    @RabbitListener(bindings =@QueueBinding(
            value = @Queue(
                    name = "error.queue", durable = "true",
                    arguments = @Argument(name = "x-queue-mode", value = "lazy")),// 设置消息队列默认为持久化和开启lazy队列模式（消息会直接存入磁盘，避免内存爆仓。）
            exchange = @Exchange(name = "error.direct", type = ExchangeTypes.DIRECT),//设置交换机名称和类型，默认为DIRECT类型与自动持久化
            key = "error" //设置队列绑定的RoutingKey
    ))
    public void listenErrorQueue(Message message, @Header(required = false) String exceptionMessage) {
        log.error("消费失败的消息，ID: {}, 内容: {}, 原因: {}",
                message.getMessageProperties().getMessageId(),
                new String(message.getBody()),
                exceptionMessage);
        // 可以记录到数据库、发告警、人工处理等
    }




}
